using System;
using System.Collections.Generic;
using Needle.Utils;

namespace Needle.Core.Activation
{

    #region ActivatorCollection

    /// <summary>
    /// A keyed nested collection of activators.
    /// </summary>
    public class ActivatorCollection : Needle.Utils.Collections.KeyedCollection<InstanceId, IActivator>
    {

        private IActivationManager m_owner;
        /// <summary>
        /// Initializes a new instance.
        /// </summary>
        public ActivatorCollection(IActivationManager owner)
            : base(x => x.Id)
        {
            Ensure.NotNull(owner, "owner");
            m_owner = owner;
        }
        /// <summary>
        /// validates and inserts a new activator.
        /// </summary>
        protected override void InsertItem(int index, IActivator item)
        {
            Ensure.NotNull(item, "item");
            base.InsertItem(index, item);
        }

        /// <summary>
        /// validates and sets a new activator.
        /// </summary>
        protected override void SetItem(int index, IActivator item)
        {
            Ensure.NotNull(item, "item");
            base.SetItem(index, item);
        }

        /// <summary>
        /// removes an activator.
        /// </summary>
        protected override void RemoveItem(int index)
        {
            base.RemoveItem(index);
        }

        /// <summary>
        /// perform action on all activators before clearing the collection.
        /// </summary>
        public void Clear(Action<IActivator> action)
        {
            Ensure.NotNull(action, "action");
            
            foreach (IActivator b in this)
                action(b);
            Clear();
        }

        /// <summary>
        /// finds the  first action satisfying the predicate.
        /// </summary>
        public IActivator Find(Predicate<IActivator> predicate)
        {
            Ensure.NotNull(predicate, "predicate");

            foreach (IActivator b in this)
                if (predicate(b))
                    return b;

            return null;
        }

        /// <summary>
        /// finds all the actions satisfying the predicate.
        /// </summary>
        public IList<IActivator> FindAll(Predicate<IActivator> predicate)
        {
            Ensure.NotNull(predicate, "predicate");

            List<IActivator> list = new List<IActivator>();
            foreach (IActivator b in this)
                if (predicate(b))
                    list.Add(b);

            return list;
        }

    }

    #endregion

}
